#include "Game.h"
#include "DXUtil.h"
#include <d3dx9.h>
#include <d3d9.h>
#include <iostream>
#include <float.h>
#include "ModelPrimitive.h"
#include "TranslateX.h"
#include "Ray.h"
#include "Sphere.h"
#include "Plane.h"
#include "math.h"
#include "HTCalc.h"
#include "NoiseSphere.h"
#include "time.h"
#include <vector>


//#define	NEAR			10.0f
//#define FAR			4000.0f
//#define	FOV			0.8f
#define	WIDTH			640.0f
#define	HEIGHT			480.0f
#define	WIDTH_DIV_2		(WIDTH*0.5f)
#define	HEIGHT_DIV_2		(HEIGHT*0.5f)
#define ASPECT			1.3333f

#define SUPER_SAMPLING_RATE   5
#define SUPER_SAMPLING	false
#define MAX_SAMPLING 10.0f

RAY Game::calcRay( Camera &cam, int x,int y,D3DXVECTOR3 &p1,D3DXVECTOR3 &p2)
{
	/*float dx,dy;
	D3DXMATRIX invMatrix,viewMatrix;

	dx=tanf(cam.GetFov()*0.5f)*(x/WIDTH_DIV_2-1.0f)/(1/cam.GetAspectRatio());
	dy=tanf(cam.GetFov()*0.5f)*(1.0f-y/HEIGHT_DIV_2);
	viewMatrix = *(cam.GetViewMatrix());

	D3DXMatrixInverse(&invMatrix, NULL, &viewMatrix);
	p1 = D3DXVECTOR3(dx*cam.GetNearPlane(), dy*cam.GetNearPlane(), cam.GetNearPlane());
	p2 = D3DXVECTOR3(dx*cam.GetFarPlane(), dy*cam.GetFarPlane(), cam.GetFarPlane());

	D3DXVECTOR4 temp;
	D3DXVec3Transform(&temp,&p1,&invMatrix);
	p1->x = temp.x;
	p1->y = temp.y;
	p1->z = temp.z;

	D3DXVec3Transform(&temp,&p2,&invMatrix);
	p2.x = temp.x;
	p2.y = temp.y;
	p2.z = temp.z;

	D3DXVECTOR3 returnVector;
	D3DXVec3Normalize(&returnVector,&D3DXVECTOR3(p2-p1));

	RAY returnRay;
	returnRay.direction = returnVector;
	returnRay.origin = p1;

	return returnRay;*/
	
	D3DXVECTOR3 pointInWorldSpace;
	D3DVIEWPORT9 viewport;
	d3ddev->GetViewport(&viewport);
	D3DXMATRIX identityMatrix;
	D3DXMatrixIdentity(&identityMatrix);
	D3DXVec3Unproject(&pointInWorldSpace, &D3DXVECTOR3(x,y,0), &viewport, cam.GetProjectionMatrix(), cam.GetViewMatrix(), &identityMatrix);

	D3DXVECTOR3 returnVector;
	D3DXVec3Normalize(&returnVector,&D3DXVECTOR3(pointInWorldSpace - *cam.GetEyePos()));

	RAY returnRay;
	returnRay.direction = returnVector;
	returnRay.origin = *cam.GetEyePos();

	return returnRay;
}



D3DXCOLOR* Game::getColor( Camera &cam, RAY ray, int depth)
{
	D3DXCOLOR* color = &D3DXCOLOR(0,0,1.0f,1.0f);

	//RAY ray = calcRay( cam, x, y, p1, p2);
	Primitive* closestPrimitive;
	closestPrimitive = &Primitive();
	
	float closestDistance = FLT_MAX ;
	
	for(int i = 0; i < mListSize; i++)
	{
		NoiseSphere* curPrim = &mObjectList[i];
		float distance = curPrim->Intersect(ray);
		if( distance > 0 && distance < closestDistance)
		{
			closestDistance = distance;
			closestPrimitive = curPrim;
		}
	}

	//create shadow ray
	if(closestDistance != FLT_MAX)
	{
		RAY shadowRay;
		shadowRay.origin = ray.origin + (ray.direction * closestDistance);
		
		closestPrimitive->GetColor(color, &shadowRay.origin);
		*color *= closestPrimitive->ambientStrength;

		//color = &(closestPrimitive->color * closestPrimitive->ambientStrength);
		D3DXCOLOR diffuse = D3DXCOLOR(0,0,0,255);
		D3DXCOLOR specular = D3DXCOLOR(0,0,0,255);

		for(int curLight = 0; curLight < mLights.size(); curLight++)
		{
			
			D3DXVec3Normalize(&shadowRay.direction, &(mLights.at(curLight)->position - shadowRay.origin));
			//shadowRay.origin += (shadowRay.direction * .0001f);

			D3DXVECTOR3* Normal = &D3DXVECTOR3(0,0,0);
			closestPrimitive->Normal(Normal, shadowRay.origin);
			float dotProd = ::D3DXVec3Dot(&shadowRay.direction, Normal);

			if( dotProd > 0)
			{
				bool shadowed = false;
				for(int i = 0; i < mListSize; i++)
				{
					NoiseSphere* curPrim = &mObjectList[i];
					if(curPrim != closestPrimitive)
					{
						float distance = curPrim->Intersect(shadowRay);
						
						if( distance >= 0 && distance != FLT_MAX)
						{
							shadowed = true;
						}
					}
				}
				if(!shadowed)
				{
					//calculate diffuse color
					diffuse += dotProd * (closestPrimitive->diffuseColor);

					//specular component
					float shadowDotNormal = D3DXVec3Dot(&shadowRay.direction, Normal);
					//D3DXVECTOR3 normalSquared = *Normal * *Normal;
					D3DXVECTOR3 reflectionVector = shadowRay.direction - (2 * *Normal * shadowDotNormal);

					D3DXVECTOR3 invertRay;
					invertRay.x = -ray.direction.x;
					invertRay.y = -ray.direction.y;
					invertRay.z = -ray.direction.z;

					float reflectDotView = ::D3DXVec3Dot(&reflectionVector, &ray.direction);
					if(reflectDotView > 0)
					{
						specular += (pow(reflectDotView, closestPrimitive->exponent) ) * (closestPrimitive->specularColor);
					}
				}
			}
		}

		*color += (diffuse * closestPrimitive->diffuseStrength) + (specular * closestPrimitive->specularStrength);
		if(depth < 10)
		{
			if(closestPrimitive->reflection > 0.0f)
			{
				D3DXCOLOR temp = D3DXCOLOR();
				closestPrimitive->Normal(&(shadowRay.direction), shadowRay.origin);
				shadowRay.direction = ray.direction - ((shadowRay.direction) * 2) * (::D3DXVec3Dot(&ray.direction, &(shadowRay.direction)));
				shadowRay.inside = false;
				temp = *(this->getColor(cam, shadowRay, depth + 1)) * closestPrimitive->reflection;

				if(SUPER_SAMPLING)
				{
					D3DXCOLOR *colors[SUPER_SAMPLING_RATE];
					colors[0] = &temp;
					for(int i = 0; i < SUPER_SAMPLING_RATE; i++)
					{
						colors[i] = new D3DXCOLOR(0,0,0,0);
						srand(time(NULL));
						float random = ((rand() % 10)/10.0f) * MAX_SAMPLING;
						shadowRay.direction.x *= random;
						random = ((rand() % 10)/10.0f) * MAX_SAMPLING;
						shadowRay.direction.y *= random;
						random = ((rand() % 10)/10.0f) * MAX_SAMPLING;
						shadowRay.direction.z *= random;
						::D3DXVec3Normalize(&shadowRay.direction, &shadowRay.direction);
						shadowRay.direction = ray.direction - ((shadowRay.direction) * 2) * (::D3DXVec3Dot(&ray.direction, &(shadowRay.direction)));
						(*colors[i]) += *(this->getColor(cam, shadowRay, depth + 1)) * closestPrimitive->reflection;
					}

					this->AverageColors(&temp, colors, 2);
					for(int i = 0; i < SUPER_SAMPLING_RATE; i++)
					{
						delete colors[i];
					}
				}
				
				*color += temp;
			}
			if(closestPrimitive->transmission > 0.0f)
			{
				float nit = 0.0f;
				D3DXVECTOR3 normal;

				/*if(closestPrimitive->sphere && ::abs(::D3DXVec3Length(&(((Sphere*)closestPrimitive)->center - ray.origin))) < ((Sphere*)closestPrimitive)->radius)
				{
					ray.inside = true;
				}
				else
				{
					ray.inside = false;
				}*/

				if(ray.inside)
				{
					nit = closestPrimitive->ior;
					closestPrimitive->Normal(&normal,shadowRay.origin);
					normal = -normal;
				}
				else
				{
					nit = 1.0f/closestPrimitive->ior;
					closestPrimitive->Normal(&normal, shadowRay.origin);
				}

				float discriminant = 1.0f + (::pow(nit,2.0f) * (::pow(::D3DXVec3Dot(&(-(ray.direction)), &normal),2.0f) - 1.0f));
				if(discriminant < 0.0f)
				{
					closestPrimitive->Normal(&(shadowRay.direction), shadowRay.origin);
					shadowRay.direction = ray.direction - ((shadowRay.direction) * 2) * (::D3DXVec3Dot(&ray.direction, &(shadowRay.direction)));
					shadowRay.inside = false;
					*color = *(this->getColor(cam, shadowRay, depth + 1)) * (closestPrimitive->transmission + closestPrimitive->reflection);
				}
				else
				{
					D3DXVECTOR3 newDirection = (nit * ray.direction) + (((nit * ::D3DXVec3Dot(&(-(ray.direction)), &normal)) - ::sqrt(discriminant)) * normal);
					::D3DXVec3Normalize(&newDirection, &newDirection);
					shadowRay.direction = newDirection;
					shadowRay.origin = shadowRay.origin + (shadowRay.direction * .00001);
					if(ray.inside)
						shadowRay.inside = false;
					else
						shadowRay.inside = true;

					*color += *(this->getColor(cam, shadowRay, depth+1)) * closestPrimitive->transmission;
				}
			}
		}
		//float multiplier = HTCalc::Turbulence(shadowRay.origin, 1,6.0);
		//*color *= multiplier;
	}

	return color;
}

D3DXCOLOR* Game::getHypertextureColor(Camera &cam, RAY ray)
{
	D3DXCOLOR* color = &D3DXCOLOR(0.0f,0.0f,0.0f,0.0f);

	Primitive* closestPrimitive;

	vector<NoiseSphere*> intersects;
	NoiseSphere* curPrim;
	for(int i = 0; i < mListSize; i++)
	{
		curPrim = &mObjectList[i];
		float distance = curPrim->Intersect(ray);
		if( distance > 0)
		{
			intersects.push_back(curPrim);
		}
	}

	for(int i = 0; i < intersects.size(); i++)
	{
		closestPrimitive = intersects.at(i);
		D3DXCOLOR* curColor = &D3DXCOLOR(0,0,0,0);
		//color = &D3DXCOLOR(1.0f,0.0f,0.0f,0.0f);
		RAY p1;
		p1.origin = ray.origin + (ray.direction * (closestPrimitive->Intersect(ray) + .001f));
		::D3DXVec3Normalize(&p1.direction, &ray.direction);
		//ray.direction = ray.direction;
	
		float distance = closestPrimitive->Intersect(p1);

		if(distance != FLT_MAX && distance > 0.0f)
		{
			int k = 0;
			D3DXVECTOR3 deltaU = (p1.direction * .1f);
			D3DXVECTOR3 temp = deltaU;
			temp.x += 1.0f;
			float cont = 0.0f;
			D3DXVECTOR3 deltaV = D3DXVECTOR3(0,0,0);
			::D3DXVec3Cross(&deltaV, &deltaU, &temp);
			::D3DXVec3Normalize(&deltaV, &deltaV);
			deltaV *= .1f;
			D3DXVECTOR3 deltaW = D3DXVECTOR3(0,0,0);
			::D3DXVec3Cross(&deltaW, &deltaV, &deltaW);
			::D3DXVec3Normalize(&deltaW,&deltaW);
			deltaW *= .1f;
			while( cont < distance)
			{
				D3DXVECTOR3 x = p1.origin + (k * deltaU);
				float value = dynamic_cast<NoiseSphere*>(closestPrimitive)->Density(x);
				float alpha = 1.0f - ::pow(1.0f-value, 1.0f * .1f);
				*curColor += ((D3DXCOLOR(1.0f,0.0f,0.0f,0.0f) * value) * alpha);
				D3DXVECTOR3 *gradient = NULL;
				D3DXCOLOR diffuse;
				if(value > 0.0f && value < 1.0f)
				{
					float fx = dynamic_cast<NoiseSphere*>(closestPrimitive)->Density(p1.origin);
					float fplusDeltaV = dynamic_cast<NoiseSphere*>(closestPrimitive)->Density(p1.origin + deltaV);
					float fplusDeltaW = dynamic_cast<NoiseSphere*>(closestPrimitive)->Density(p1.origin + deltaW);
					float value1 =  fx - value;
					gradient = &D3DXVECTOR3(fx - value, fplusDeltaV - fx, fplusDeltaW + fx);
					::D3DXVec3Normalize(gradient, gradient);
					RAY shadowRay;
					shadowRay.origin = x;
					D3DXVec3Normalize(&shadowRay.direction, &(mLights.at(0)->position - shadowRay.origin));
					float dotProd = ::D3DXVec3Dot(&shadowRay.direction, gradient);
					if(dotProd > 0)
					{
						diffuse = dotProd * (D3DXCOLOR(1.0f,0.0f,0.0f,0.0f));
					}
					else
					{
						diffuse = -dotProd * (D3DXCOLOR(1.0f,0.0f,0.0f,0.0f));
					}
				}
				//*color += (diffuse * closestPrimitive->diffuseStrength);
				cont = ::D3DXVec3Length(&(x-p1.origin));
				k++;
			}
			*color += *curColor;
		}
	}
	return color;
}

void Game::AverageColors(D3DXCOLOR* output, D3DXCOLOR* color[], int n)
{
	//D3DCOLOR* sum;
	float sum[3];
	sum[0] = 0;
	sum[1] = 0;
	sum[2] = 0;

	for(int i = 0; i < n; i++)
	{
		sum[0] += color[i]->r;
		sum[1] += color[i]->g;
		sum[2] += color[i]->b;
	}
	sum[0] /= (float)n;
	sum[1] /= (float)n;
	sum[2] /= (float)n;

	output = &D3DXCOLOR(sum[0],sum[1],sum[2],255);
}

void Game::Initialize()
{
	frameCount = 0;
	D3DXMatrixIdentity(&mIdentity);
	IniScene();
	//LoadContent(d3ddev);
}

void Game::Update( double pElapsedTime) 
{
	ft->Update(pElapsedTime);
	mObjectList = ft->GetPrimitives(&mListSize);
	//mCamera->GetEyePos()->z+=0.1f;
	//mCamera->GetEyePos()->x+=0.05;
	//mCamera->GetEyePos()->y+=0.025;
}

D3DVECTOR* Game::DetermineEllipseTangent(D3DVECTOR* circle,D3DVECTOR* point )
{
     // This is just an implementation of the equation in the tutorial. All we need is a vector
     // giving the direction of the tangent, hence we only pay attention to the final terms.
 
     // The variable t is simply a parameter to the equation. We are only paying attention to
     // the final terms, and since they give the slope (i.e., the direction of the tangent), we
     // let t = 1.
 
   //  D3DVECTOR tangent = new D3DVECTOR();
    // tangent.x = point->x - (Ellipse->z* point->y)/Ellipse->z;
     //tangent.y = point->y + (Ellipse->z*point->x)/Ellipse->z;
	return NULL;
   //  return &tangent;     
}

void Game::IniScene(){

	
	mCamera = new Camera();

	D3DVIEWPORT9 view;
	d3ddev->GetViewport( &view);
	mCamera->SetAspectRatio(((float)view.Width)/view.Height);
	
	mCamera->GetEyePos()->x = 0.0f;
	mCamera->GetEyePos()->y = 0.0f;
	mCamera->GetEyePos()->z = -6.0f;
	
	mCamera->GetLookAt()->x = 0.0f;
	mCamera->GetLookAt()->y = 0.0f;
	mCamera->GetLookAt()->z = 0.0f;

	mCamera->SetFov(D3DXToRadian(60.0f));

	D3DXVECTOR3	temp1, temp2;


	NoiseSphere* s1 = new NoiseSphere();
	s1->center = D3DXVECTOR3(1.0f,1.0f,1.0f);
	s1->radius = 1.0f;
	s1->radiusInner = 0.0f;
	s1->color = D3DCOLOR_XRGB(0,255,0);
	s1->ambientStrength = .3f;
	s1->diffuseColor = D3DCOLOR_XRGB(0,255,0);
	s1->diffuseStrength = .5f;
	s1->specularColor = D3DXCOLOR(255,255,255,255);
	s1->specularStrength = .05f;
	s1->exponent = 100.0f;
	s1->shadingOn = true;
	s1->reflection = 0.0f;
	s1->transmission = 0.0f;
	s1->ior = .95f;
	//mObjectList.push_back(s1);

	NoiseSphere* s2 = new NoiseSphere();
	s2->center = D3DXVECTOR3(0.0f,0.0f,0.0f);
	s2->radius = 1.0f;
	s2->radiusInner = 0.0f;
	s2->color = D3DCOLOR_XRGB(0,255,0);
	s2->ambientStrength = .8f;
	s2->diffuseColor = D3DCOLOR_XRGB(0,255,0);
	s2->diffuseStrength = .5f;
	s2->specularColor = D3DXCOLOR(255,255,255,255);
	s2->specularStrength = .05f;
	s2->exponent = 100.0f;
	s2->shadingOn = true;
	s2->reflection = 0.0f;
	s2->transmission = 0.0f;
	s2->ior = .95f;
	//mObjectList.push_back(s2);

	/*Sphere* s2 = new Sphere();
	s2->center = D3DXVECTOR3(-1.25f,-1.5f,1.0f);
	s2->radius = 1.0f;
	s2->color = D3DCOLOR_XRGB(255,255,0);
	s2->ambientStrength = .3f;
	s2->diffuseColor = D3DCOLOR_XRGB(220,220,220);
	s2->diffuseStrength = .5f;
	s2->specularColor = D3DXCOLOR(255,255,255,255);
	s2->specularStrength = .05f;
	s2->exponent = 200.0f;
	s2->shadingOn = true;
	s2->reflection = .5f;
	s2->transmission = 0.0f;
	s2->ior = 0.0f;*/
	//mObjectList.push_back(s2);

	Plane* p1 = new Plane();;
	p1->Distance = 4.0f;
//	D3DXVec3Normalize(p1->Normal(D3DXVECTOR3(0,0,0)), &D3DXVECTOR3(0,1.0f,0));
	p1->point = D3DXVECTOR3(-15.0f, 0.0f, -10.0f);
	p1->Width = 25.0f;
	p1->Depth = 50.0f;
	p1->color = D3DCOLOR_XRGB(255,0,0);
	p1->ambientStrength = .3f;
	p1->diffuseColor = D3DCOLOR_XRGB(255,255,255);
	p1->diffuseStrength = .3f;
	p1->specularColor = D3DXCOLOR(255,255,255,255);
	p1->specularStrength = 0.0f;
	p1->exponent = 200.0f;
	p1->shadingOn = true;
	p1->textureCenter = D3DXVECTOR2(p1->point.x + 7, p1->point.y);
	p1->reflection = 0.0f;
	p1->transmission = 0.0f;
	p1->ior = 0.0f;
	//mObjectList.push_back(p1);

	LIGHT* tempLight = new LIGHT();
	tempLight->position = D3DXVECTOR3(-10,10,0);
	mLights.push_back(tempLight);

	LIGHT* tempLight2= new LIGHT();
	tempLight2->position = D3DXVECTOR3(10,10,0);
	mLights.push_back(tempLight2);

	ambientLight = D3DXCOLOR(255,255,255,255);
	ambientStrength = .1f;

	image = new D3DXCOLOR[(int)(HEIGHT*WIDTH)];

	int index = 0;
	for(int i =0;  i < HEIGHT; i++){
		for(int j =0;  j < WIDTH; j++){
			index = i*WIDTH + j;
			image[index].a = 255.0f;
			image[index].r = 0.0f;
			image[index].g = 0.0f;
			image[index].b = 0.0f;
		}
	}
	index =0;

	ft = new FractalTree();

	HTCalc::Initialize();
}

void Game::LoadContent(){
	for(int i = 0; i < mModels.size(); i++ )
	{
		mModels[i]->LoadContent(d3ddev);
	}
}

//Draws the list of models
void Game::Draw(){

	D3DXCOLOR* colorArray[SUPER_SAMPLING_RATE];
	D3DXCOLOR* color = &D3DXCOLOR(0,0,0,255);

	int index = 0;
	for(int i = 0; i <WIDTH; i++)
	{
		for(int j = 0; j < HEIGHT; j++)
		{
			index = j*WIDTH + i;
			RAY ray = this->calcRay(*mCamera, i, j, D3DXVECTOR3(), D3DXVECTOR3());
			ray.inside = false;
			color = this->getHypertextureColor(*mCamera, ray);
			
			/*if(SUPER_SAMPLING)
			{		
				colorArray[0] = color;
				for(int i = 1; i < SUPER_SAMPLING_RATE; i++)
				{
					srand(time(NULL));
					float randomx = ((rand() % 10)/10.0f) * MAX_SAMPLING;
					float randomy = ((rand() % 10)/10.0f) * MAX_SAMPLING;
					float randomz = ((rand() % 10)/10.0f) * MAX_SAMPLING;
					mCamera->GetEyePos()->x += randomx;
					mCamera->GetEyePos()->y += randomy;
					mCamera->GetEyePos()->z += randomz;
					colorArray[i] = this->getColor( *mCamera, ray, 0);
					mCamera->GetEyePos()->x -= randomx;
					mCamera->GetEyePos()->y -= randomy;
					mCamera->GetEyePos()->z -= randomz;
				}

				this->AverageColors(color, colorArray, 1);
			}*/
			
			image[index].a = color->a;
			image[index].r = color->r;
			image[index].g = color->g;
			image[index].b = color->b;
		}
	}

	//Present();

	
//Screen Cap
		
	
	/*IDirect3DSurface9 *texture = NULL;

	d3ddev->CreateOffscreenPlainSurface(WIDTH, HEIGHT, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, NULL);

	D3DLOCKED_RECT rect;
	texture->LockRect(&rect, NULL, 0);
	::CopyMemory(static_cast<BYTE *>(rect.pBits), image, sizeof(image)); 
	texture->UnlockRect();*/
}

void Game::ScreenShot(){

	string s = "frame";
		
		std::string frames;
		std::stringstream out;
		out << frameCount++;
		frames = out.str();
		
		s.append(frames);
		s.append(".png");

		//LPDIRECT3DSURFACE9		Surface;
		::IDirect3DSurface9* Surface;

		//pDev->GetDisplayMode( 0, &DisplayMode );

		// Grab the current image in our front buffer.
		d3ddev->CreateOffscreenPlainSurface( 640, 480, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &Surface, NULL );

		// Copy everything from the front buffer to our surface.
			d3ddev->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO,&Surface );

		// Write the contents of the surface to the given file.
		D3DXSaveSurfaceToFile( s.c_str(), D3DXIFF_BMP, Surface, NULL, NULL);

		// Finally, free the image surface.
		Surface->Release( );
		Surface = NULL;

}

void Game::Release(){
	for(int i = 0; i < mModels.size(); i++ )
	{
		mModels[i]->Release();
	}
	delete mCamera;
	//delete this->image;
//	d3ddev->Release();    // close and release the 3D device
   // d3d->Release();    // close and release Direct3D
}


// this function initializes and prepares Direct3D for use
void Game::initD3D(HWND hWnd)
{
    d3d = Direct3DCreate9(D3D_SDK_VERSION);

    D3DPRESENT_PARAMETERS d3dpp;

    ZeroMemory(&d3dpp, sizeof(d3dpp));
	d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.hDeviceWindow = hWnd;
    d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
    d3dpp.BackBufferWidth = 640;
    d3dpp.BackBufferHeight = 480;
    d3dpp.EnableAutoDepthStencil = TRUE;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

    // create a device class using this information and the info from the d3dpp stuct
    d3d->CreateDevice(D3DADAPTER_DEFAULT,
                      D3DDEVTYPE_HAL,
                      hWnd,
                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                      &d3dpp,
                      &d3ddev);

	d3ddev->SetRenderState(D3DRS_LIGHTING, TRUE);    // turn on the 3D lighting
    d3ddev->SetRenderState(D3DRS_ZENABLE, TRUE);    // turn on the z-buffer
    d3ddev->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(50, 50, 50));    // ambient light

	d3ddev->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 255), 1.0f, 0); // clear frame
	d3ddev->Present(NULL,NULL,NULL,NULL);
    return;
}


void Game::Present(){
	IDirect3DSurface9 *backBuffer = NULL;
	//d3ddev->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 255, 0), 1.0f, 0); // clear frame

	d3ddev->BeginScene();
	d3ddev->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO, &backBuffer);

	D3DXCOLOR* color = NULL;
	int index = 0;
	for(int i = 0; i <WIDTH; i++)
	{
		for(int j = 0; j < HEIGHT; j++)
		{
			index = j*WIDTH + i;
			RECT fillRect;
			fillRect.bottom = j+1;
			fillRect.top = j;
			fillRect.right = i+1;
			fillRect.left = i;		
			color =  &image[index];
			d3ddev->ColorFill(backBuffer, &fillRect, *color);
		}
	}

	d3ddev->EndScene();
	d3ddev->Present(NULL,NULL,NULL,NULL);
}
